The API is multi-threaded, and updates from the server can occur while you are accessing the API objects and properties. This means that if you are updating a user interface then you will need to marshal the events (e.g. MarketDepthUpdate) onto your main UI thread. This can be done using the BeginInvoke method of any .Net control.
NOTE: Using BeginInvoke is preferable to using Invoke as this allows the API to continue processing whereas Invoke will block the API until the method completes and can cause deadlocks in some circumstances.
Also, it is possible for your application to throw errors while processing any collection based object in the API, even if it does not have a UI. For example, the collection of Depth items (bids and offers) for a market could change while you are iterating through it. To prevent this most of the API objects provide a SyncRoot property, EnterLock and ExitLock methods. When EnterLock is called on an object it will block any updates from the server to it, and to it’s children. For example, EnterLock on the Account object would block any updates to the account itself, to it’s positions and to it’s orders. Consequently you should keep locks active for the shortest amount of time possible. You must also ensure that you call ExitLock for every EnterLock call. It is highly recommended that you place the locks within a Try – Finally block as shown below. The only difference between using SyncRoot and the EnterLock/ExitLock methods is that the later can provide trace information which is useful in dealing with deadlock problems.
' Deal with the Market Depth Updating.
Private Sub moMarket_MarketDepthUpdate(ByVal poMarket As Market) Handles moMarket.MarketDepthUpdate
' Invoke the update on the main UI thread if needed.
If Me.InvokeRequired Then
Me.BeginInvoke(New MethodInvoker(AddressOf MarketDepthUpdate))
Else
MarketDepthUpdate()
End If
End Sub
' Update the display.
Private Sub MarketDepthUpdate()
' Lock the market object so that we can safely process the depth.
Try
moMarket.EnterLock()
' Display the market depth.
Finally
' Make sure that we exit the lock regardless of anything else that happens.
moMarket.ExitLock()
End Try
End Sub